﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Collections.Concurrent;
using System.Threading;
namespace ClassLibraryMessageDispacher
{
    public sealed class ClassMessagerDispacher
    {
        public bool isInitInstance =false;
        public static readonly ClassMessagerDispacher  instance = new ClassMessagerDispacher();
        private ConcurrentQueue<MessagePackage> q = new ConcurrentQueue<MessagePackage>();
        private FunctionMessageOutCom dbmesOut = null;
        public FunctionMessageOutCom uimesOut = null;
        public FunctionMessageOutCom middleDevNetOut = null;
        private Thread disthread = null;
        private ushort addSquence = 0;
        public ushort GetSquence()
        {
            addSquence++;
            if (addSquence >= 0xffff) addSquence = 0;
            return addSquence;
        }
        /// <summary>
        /// 注意: dbcom委托函数一定不可以有时间阻塞，否则影响消息分发。
        /// 建议方法，回调此函数，db数据库模块，将消息存储在队列中，开线程或者异步去处理。
        /// </summary>
        /// <param name="dbcom"></param>
        public void registerDBmesOut(FunctionMessageOutCom dbcom)
        {
            dbmesOut = dbcom;
        }
        private ClassMessagerDispacher()
            {
            isInitInstance = true;
             disthread = new Thread(back_dispacher_thread);
            disthread.Priority = ThreadPriority.Normal;
            disthread.IsBackground = true;
            disthread.Start();
            }
        ~ClassMessagerDispacher()
        {
            disthread.DisableComObjectEagerCleanup();
        }
        public void PushMessageIn(ref MessagePackage mes)
        {
            try
            {
                if (q.Count <= 10)
                {
                    q.Enqueue(mes);
                }
                else
                {

                }
            }catch(Exception e)
            {
                Console.WriteLine(e.Message);
            }
          
        }

        public int GetMessageQuenueCount()
        {
            return q.Count;
        }
        private void back_dispacher_thread(object inparam)
        {
            while(true)
            {
                Thread.Sleep(50);         
                if(q.TryDequeue(out MessagePackage outmessage))
                {
                    bool issent = false;
                    switch(outmessage.dest)
                    {
                        case MessagePackagePath.None:
                            {

                            } break;

                        case MessagePackagePath.DBCom:
                            {
                                if(dbmesOut!=null)
                                {
                                    dbmesOut(ref outmessage);
                                    issent = true;
                                }
                                else
                                {

                                }

                            }break;
                        case MessagePackagePath.UICom:
                            {
                                if (uimesOut != null)
                                {
                                    uimesOut(ref outmessage);
                                    issent = true;
                                }
                                else
                                {

                                }

                            }
                            break;
                        case MessagePackagePath.NetMiddleDeviceCom:
                            {
                                if (middleDevNetOut != null)
                                {
                                    middleDevNetOut(ref outmessage);
                                    issent = true;
                                }
                                else
                                {

                                }

                            }
                            break;
                        default:break;

                    }

                    if(!issent)
                    {
                        q.Enqueue(outmessage);
                    }

                }else
                {
                    continue;
                }


            }

        }

    }
}
